package com.flow.asyncflow.core.utils.mongodb;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flow.asyncflow.core.entity.asyncFlowMonitor.AsyncFlowLogVo;
import com.flow.asyncflow.core.entity.log.asyncflowlog.AsyncFlowLogEntity;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class MongoHelper<T> {
    private MongoDatabase mongoDataBase;
    private MongoClient mongoClient;
    private MongoCollection<Document> collection;
    // List<ServerAddress> addresses = new ArrayList<ServerAddress>();
    // ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017);
    // ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017);
    // ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017);

    public MongoHelper(List<com.mongodb.ServerAddress> addresses, String dBName, String table) {
        mongoClient = new MongoClient(addresses);
        mongoDataBase = mongoClient.getDatabase(dBName);
        collection = mongoDataBase.getCollection(table);
    }

    public MongoHelper(String url, String dBName, String table) {
        mongoClient = new MongoClient(new MongoClientURI(url));
        mongoDataBase = mongoClient.getDatabase(dBName);
        collection = mongoDataBase.getCollection(table);
    }

    /**
     * 查找对象 - 根据主键_id
     *
     * @param id 主键ID
     * @return 返回
     */
    public Document findById(String id) {
        ObjectId _idol = null;
        try {
            _idol = new ObjectId(id);
        } catch (Exception e) {
            return null;
        }
        return collection.find(Filters.eq("_id", _idol)).first();
    }

    /**
     * 统计数
     */
    public int getCount(Bson filter) {
        return (int) collection.count(filter);
    }

    /**
     * @param document 添加实体
     * @return 是否成功
     */
    public boolean insertOne(Document document) {
        collection.insertOne(document);
        long count = collection.count(document);
        return count >= 1;
    }


    /**
     * 条件查询
     */
    public MongoCursor<Document> find(Bson filter) {
        return collection.find(filter).iterator();
    }

    /**
     * 分页查询
     */
    public MongoCursor<Document> findByPage(Bson filter, int pageNo, int pageSize) {
        Bson orderBy = new BasicDBObject("asyncFlowDateTime", -1);
        return collection.find(filter).skip((pageNo - 1) * pageSize).limit(pageSize).iterator();
    }



    /**
     * 获取需要操作的实体类class
     *
     * @return 返回类型
     */
    private Class<T> getEntityClass() {
        Type superclass = this.getClass().getGenericSuperclass();
        Type[] actualTypeArguments = ((ParameterizedType) superclass).getActualTypeArguments();
        return (Class) actualTypeArguments[0];
    }



    /**
     * @param id          主键
     * @param newDocument 要插入的文档
     * @return 文档
     */
    public Document updateById(String id, Document newDocument) {
        ObjectId _idol = null;
        try {
            _idol = new ObjectId(id);
        } catch (Exception e) {
            return null;
        }
        Bson filter = Filters.eq("_id", _idol);
        collection.updateOne(filter, new Document("$set", newDocument));
        return newDocument;
    }

    public <T> Document toDocument(T object) {

        String json = JSON.toJSONString(object);

        return Document.parse(json);

    }

    public <T> T toBean(Document document, Class<T> clzz) {

        String realJson = document.toJson();

        return JSON.parseObject(realJson, clzz);
    }

    public void closeMongoClient() {

        if (mongoDataBase != null) {
            mongoDataBase = null;
        }
        if (mongoClient != null) {
            mongoClient.close();
        }
    }
}
